﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;

public class CodeGenerator
{
    public static float String5ToFloat1_3(string s)
    {
        if (s.Length != 5) throw new Exception();
        int i;
        int.TryParse(s, out i);
        float v = i * 0.001f;
        return v;
    }
    public static string Float1_3ToString5(float v)
    {
        v *= 1000;
        int i = (int)v;
        var format = "0000"; // 整数1位 + 小数3位 + 符号1位
        var s = i.ToString(format);
        if (i >= 0) s = "+" + s;
        if (s.Length != 5) { Debug.LogError(s); throw new Exception("len diff"); }
        return s;
    }
    public static float String6ToFloat3_2(string s)
    {
        if (s.Length != 6) throw new Exception();
        int i;
        int.TryParse(s, out i);
        float v = i * 0.01f;
        return v;
    }
    public static string Float3_2ToString6(float v)
    {
        v *= 100;
        int i = (int)v;
        var format = "00000"; // 整数3位 + 小数2位 + 符号1位
        var s = i.ToString(format);
        if (i >= 0) s = "+" + s;
        if (s.Length != format.Length + 1) { Debug.LogError(s); throw new Exception("len diff"); }
        return s;
    }
}
public class MatCodeGenerator
{
    public MatCodeGenerator(SliderMgr sm)
    {
        this.sm = sm;
    }
    public SliderMgr sm;
    public Color rangeHlColor;
    public float rangeHlPower;
    public Color rimColor;
    public float rimPower;
    public bool rimOn;
    public Color matCapColor;
    public Color lightColor;
    public float darkStep;
    public float darkFeather;
    public Color darkColor;
    public float dark2Step;
    public float dark2Feather;
    public Color dark2Color;
    public Vector2 matCapOffset;
    public Vector2 matCapScale;
    public string matCapFileName;

    public string data;
    //public bool busy;

    public const float hex2factor = 1f / 255f;
    float Hex2ToFloat
    {
        get
        {
            string hex = Read(2); // no sign
            int d = Int32.Parse(hex, System.Globalization.NumberStyles.HexNumber);
            float v = d * hex2factor;
            return v;
        }
    }
    public string colorMark = "C";
    public string mark = "0";
    Color Hex6ToColor
    {
        get
        {
            mark = Read(colorMark.Length);
            if (!mark.Equals(colorMark, StringComparison.InvariantCultureIgnoreCase)) throw new Exception("Color Mark miss");
            Color c = new Color(Hex2ToFloat, Hex2ToFloat, Hex2ToFloat);
            return c;
        }
    }
    string ColorToHex6(Color c)
    {
        var format = "X2";
        var range = 255;
        int r = (int)(c.r * range);
        int g = (int)(c.g * range);
        int b = (int)(c.b * range);
        return colorMark + r.ToString(format) + g.ToString(format) + b.ToString(format);
    }
    public float String5ToFloat1_3
    {
        get
        {
            string s = Read(5);
            int i;
            int.TryParse(s, out i);
            float v = i * 0.001f;
            return v;
        }
    }
    public string Float1_3ToString5(float v)
    {
        v *= 1000;
        int i = (int)v;
        var format = "0000"; // 整数1位 + 小数3位 + 符号1位
        var s = i.ToString(format);
        if (i >= 0) s = "+" + s;
        if (s.Length != 5) { Debug.LogError(s); throw new Exception("len diff"); }
        return s;
    }
    public float String6ToFloat3_2
    {
        get
        {
            string s = Read(6);
            int i;
            int.TryParse(s, out i);
            float v = i * 0.01f;
            return v;
        }
    }
    public string Float3_2ToString6(float v)
    {
        v *= 100;
        int i = (int)v;
        var format = "00000"; // 整数3位 + 小数2位 + 符号1位
        var s = i.ToString(format);
        if (i >= 0) s = "+" + s;
        if (s.Length != format.Length + 1) { Debug.LogError(s); throw new Exception("len diff"); }
        return s;
    }
    public Vector3 String15ToVector3
    {
        get
        {
            Vector3 v;
            v.x = String5ToFloat1_3;
            v.y = String5ToFloat1_3;
            v.z = String5ToFloat1_3;
            return v;
        }
    }
    public string Vector3ToString15(Vector3 v)
    {
        string s = Float1_3ToString5(v.x) + Float1_3ToString5(v.y) + Float1_3ToString5(v.z);
        return s;
    }
    private int String4ToInt
    {
        get
        {
            string s = Read(4);
            int i;
            int.TryParse(s, out i);
            return i;
        }
    }
    private string IntToString4(int i)
    {
        var s = i.ToString("000");// 3num + 1sign
        if (i >= 0) s = "+" + s;
        return s;
    }
    public bool String1ToBool
    {
        get
        {
            string s = Read(1); // no sign
            int i;
            int.TryParse(s, out i);
            bool v = i != 0;
            return v;
        }
    }
    public string BoolToString1(bool v)
    {
        int i = v ? 1 : 0;
        return i.ToString();
    }
    string Read(int count)
    {
        var sec = data.Substring(0, count);
        data = data.Substring(count);
        return sec;
    }
    public int signIndex;
    public void SetCodeToMat(Material mat, string v)
    {
        //if (busy) return;
        //busy = true;
        data = v;

        mat.SetColor(sm.rangeHlName, Hex6ToColor);
        mat.SetFloat(sm.rangeHlPowerName, String6ToFloat3_2);

        mat.SetColor(sm.rimName, Hex6ToColor);
        mat.SetFloat(sm.rimPowerName, String6ToFloat3_2);
        mat.SetFloat(sm.rimToggleName, String1ToBool ? 1 : 0);

        mat.SetColor(sm.matCapName, Hex6ToColor);
        mat.SetColor(sm.lightName, Hex6ToColor);

        mat.SetColor(sm.darkName, Hex6ToColor);
        mat.SetFloat(sm.darkStepName, String6ToFloat3_2);
        mat.SetFloat(sm.darkFeatherName, String6ToFloat3_2);

        mat.SetColor(sm.dark2Name, Hex6ToColor);
        mat.SetFloat(sm.dark2StepName, String6ToFloat3_2);
        mat.SetFloat(sm.dark2FeatherName, String6ToFloat3_2);

        mat.SetTextureScale(sm.matCapTexName, new Vector2(String6ToFloat3_2, String6ToFloat3_2));
        mat.SetTextureOffset(sm.matCapTexName, new Vector2(0, String6ToFloat3_2));

        //busy = false;
    }
    public string GetMaterialCode(Material mat)
    {
        string str = "";
        str += ColorToHex6(mat.GetColor(sm.rangeHlName));
        str += Float3_2ToString6(mat.GetFloat(sm.rangeHlPowerName));

        str += ColorToHex6(mat.GetColor(sm.rimName));
        str += Float3_2ToString6(mat.GetFloat(sm.rimPowerName));
        str += BoolToString1(mat.GetFloat(sm.rimToggleName) > 0 ? true : false);

        str += ColorToHex6(mat.GetColor(sm.matCapName));
        str += ColorToHex6(mat.GetColor(sm.lightName));

        str += ColorToHex6(mat.GetColor(sm.darkName));
        str += Float3_2ToString6(mat.GetFloat(sm.darkStepName));
        str += Float3_2ToString6(mat.GetFloat(sm.darkFeatherName));

        str += ColorToHex6(mat.GetColor(sm.dark2Name));
        str += Float3_2ToString6(mat.GetFloat(sm.dark2StepName));
        str += Float3_2ToString6(mat.GetFloat(sm.dark2FeatherName));

        str += Float3_2ToString6(mat.GetTextureScale(sm.matCapTexName).x);
        str += Float3_2ToString6(mat.GetTextureScale(sm.matCapTexName).y);
        str += Float3_2ToString6(mat.GetTextureOffset(sm.matCapTexName).y);
        return str;
    }
}
